home *** CD-ROM | disk | FTP | other *** search
- /*
- * PatchAssign.c
- * © LFSoft 1995
- *
- * Notify when assign are changed.
- *
- * Version 1.0
- * 30/07/1995 First version. Resource "ASSIGN"
- * 02/08/1995 More tests for cleanup()
- *
- * Version 1.1
- * 07/08/1995 Why only notifing for assign? New resources "RESIDENT" and
- * "ENVVAR" allow notification for resident commands and for
- * environnement variables.
- * ^
- * /!\ CAUTION: Removing patch is never a safe thing !
- * ¯T¯
- * NOTE: + When a delayed resident (in a CSH compatible way - CSH 5.20+,
- * LFSystemBinder, ...- ) is added (or deleted) you are notified for ENVVAR
- * modification. When a delayed resident is invoqued for the first time, you
- * are notified from "ENVVAR" and "RESIDENT".
- * + For EnvVar my first idea was to use a DOS notification, but,
- * unfortunaly, variable deletion isn't notified. So, i patch SetVar() and
- * DeleteVar() too and i look for !GVF_LOCAL_ONLY flag. We still need to use
- * dos notifications for programs that directly write to ENV: like my very own
- * DiceConfig...
- * + Already locked "ASSIGN" resource meens PatchAssign is already
- * running.
- *
- * CTRL-C for exist.
- *
- * This code is fully a dommain public: Use it as you want...
- * Note: This code use my very own LFatal() function to display an alert
- * when error occur. You must change it to a new one if you want to compile
- * this source.
- *
- */
-
- #include <proto/exec.h>
- #include <proto/registry.h>
- #include <proto/dos.h>
- #include <LF.h> // For LFatal()
- #include <stdio.h>
- #include <stdlib.h>
-
- extern struct Library *DOSBase;
- struct Library *RegistryBase=NULL;
-
- APTR resass=NULL, resres = NULL, resenv = NULL;
-
- struct NotifyRequest req;
-
- BOOL (*oldfaa)(__D1 STRPTR,__D2 BPTR) = NULL; // AssignAdd
- BOOL (*oldfalt)(__D1 STRPTR,__D2 STRPTR) = NULL; // AssignLate
- BOOL (*oldfalc)(__D1 STRPTR,__D2 BPTR) = NULL; // AssignLock
- BOOL (*oldfap)(__D1 STRPTR,__D2 STRPTR) = NULL; // AssignPath
- BOOL (*oldfra)(__D1 STRPTR,__D2 BPTR) = NULL; // RemAssignList
-
- LONG (*oldfas)(__D1 STRPTR, __D2 BPTR, __D3 LONG) = NULL; // AddSegment
- LONG (*oldfrs)(__D1 struct Segment *) = NULL; // RemSegment
-
- BOOL (*oldfsv)(__D1 STRPTR, __D2 STRPTR, __D3 LONG, __D4 ULONG) = NULL; // SetVar
- BOOL (*oldfdv)(__D1 STRPTR,__D2 ULONG) = NULL; // DeleteVar
-
- BOOL regassok = FALSE;
-
- void cleanup() {
- if(RegistryBase){
- if(regassok) RL_UnLockResource(resass);
- RL_UnRegisterResource(resass);
- RL_UnRegisterResource(resres);
- RL_UnRegisterResource(resenv);
- CloseLibrary(RegistryBase);
- }
- }
-
- __geta4 BOOL myassadd(__D1 STRPTR nom, __D2 BPTR path){
- BOOL ret = oldfaa(nom,path);
- if(ret) RL_Notify(resass);
- return ret;
- }
-
- __geta4 BOOL myasslate(__D1 STRPTR nom, __D2 STRPTR path){
- BOOL ret = oldfalt(nom,path);
- if(ret) RL_Notify(resass);
- return ret;
- }
-
- __geta4 BOOL myasslock(__D1 STRPTR nom, __D2 BPTR path){
- BOOL ret = oldfalc(nom,path);
- if(ret) RL_Notify(resass);
- return ret;
- }
-
- __geta4 BOOL myasspath(__D1 STRPTR nom, __D2 STRPTR path){
- BOOL ret = oldfap(nom,path);
- if(ret) RL_Notify(resass);
- return ret;
- }
-
- __geta4 BOOL myremasslist(__D1 STRPTR nom, __D2 BPTR path){
- BOOL ret = oldfra(nom,path);
- if(ret) RL_Notify(resass);
- return ret;
- }
-
- __geta4 LONG myaddsegment(__D1 STRPTR nom, __D2 BPTR seg, __D3 LONG type){
- LONG ret = oldfas(nom,seg,type);
- if(ret) RL_Notify(resres);
- return ret;
- }
-
- __geta4 LONG myremsegemnt(__D1 struct Segment *seg){
- LONG ret = oldfrs(seg);
- if(ret) RL_Notify(resres);
- return ret;
- }
-
- __geta4 BOOL mysetvar(__D1 STRPTR name, __D2 STRPTR buffer, __D3 LONG size, __D4 ULONG flags){
- BOOL ret = oldfsv(name,buffer,size,flags);
- if(ret && !(flags & GVF_LOCAL_ONLY)) RL_Notify(resenv);
- return ret;
- }
-
- __geta4 BOOL mydeletevar(__D1 STRPTR name, __D2 ULONG flags){
- BOOL ret = oldfdv(name,flags);
- if(ret && !(flags & GVF_LOCAL_ONLY)) RL_Notify(resenv);
- return ret;
- }
-
- void debut( void ){
- if(!(RegistryBase = OpenLibrary("registry.library",0))){
- LFatal("Can't open registry.library");
- exit(20);
- }
- atexit(cleanup);
-
- req.nr_Name = "Env:";
- req.nr_Flags = NRF_SEND_SIGNAL;
- req.nr_stuff.nr_Signal.nr_Task = FindTask(NULL);
- req.nr_stuff.nr_Signal.nr_SignalNum = SIGBREAKB_CTRL_F;
-
- if(!StartNotify(&req)){
- puts("Error from StartNotify(\"Env:\")");
- exit(20);
- }
-
- // register our resouces
- if(!(resass=RL_RegisterResource("ASSIGN"))){
- LFatal("Can't register my resouce");
- exit(20);
- }
-
- if(!(resres=RL_RegisterResource("RESIDENT"))){
- LFatal("Can't register my resouce");
- exit(20);
- }
-
- if(!(resenv=RL_RegisterResource("ENVVAR"))){
- LFatal("Can't register my resouce");
- exit(20);
- }
-
- // Lock exclusively the resource
- if(!(regassok = RL_LockResource(resass,FALSE))){
- LFatal("PatchAssign should be already running");
- exit(20);
- }
-
- oldfaa = SetFunction(DOSBase, -630, myassadd);
- oldfalt = SetFunction(DOSBase, -618, myasslate);
- oldfalc = SetFunction(DOSBase, -612, myasslock);
- oldfap = SetFunction(DOSBase, -624, myasspath);
- oldfra = SetFunction(DOSBase, -636, myremasslist);
-
- oldfas = SetFunction(DOSBase, -774, myaddsegment);
- oldfrs = SetFunction(DOSBase, -786, myremsegemnt);
-
- oldfsv = SetFunction(DOSBase, -900, mysetvar);
- oldfdv = SetFunction(DOSBase, -912, mydeletevar);
-
- FOREVER {
- ULONG sig = Wait(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_F);
-
- if(sig & SIGBREAKF_CTRL_F)
- RL_Notify(resenv);
-
- if(sig & SIGBREAKF_CTRL_C){
- APTR vect;
- BOOL ok = TRUE;
-
- Forbid(); // Test if nobody have changed our patch
-
- vect = SetFunction(DOSBase, -630, NULL);
- SetFunction(DOSBase, -630, vect);
- if(vect != myassadd) ok = FALSE;
-
- vect = SetFunction(DOSBase, -618, NULL);
- SetFunction(DOSBase, -618, vect);
- if(vect != myasslate) ok = FALSE;
-
- vect = SetFunction(DOSBase, -612, NULL);
- SetFunction(DOSBase, -612, vect);
- if(vect != myasslock) ok = FALSE;
-
- vect = SetFunction(DOSBase, -624, NULL);
- SetFunction(DOSBase, -624, vect);
- if(vect != myasspath) ok = FALSE;
-
- vect = SetFunction(DOSBase, -636, NULL);
- SetFunction(DOSBase, -636, vect);
- if(vect != myremasslist) ok = FALSE;
-
- vect = SetFunction(DOSBase, -774, NULL);
- SetFunction(DOSBase, -774, vect);
- if(vect != myaddsegment) ok = FALSE;
-
- vect = SetFunction(DOSBase, -786, NULL);
- SetFunction(DOSBase, -786, vect);
- if(vect != myremsegemnt) ok = FALSE;
-
- vect = SetFunction(DOSBase, -900, NULL);
- SetFunction(DOSBase, -900, vect);
- if(vect != mysetvar) ok = FALSE;
-
- vect = SetFunction(DOSBase, -912, NULL);
- SetFunction(DOSBase, -912, vect);
- if(vect != mydeletevar) ok = FALSE;
-
- if(ok) break;
- else {
- Permit();
- LFatal("PatchAssign can't be removed");
- }
- }
- }
-
- SetFunction(DOSBase, -630, oldfaa); // AssignAdd
- SetFunction(DOSBase, -618, oldfalt); // AssignLate
- SetFunction(DOSBase, -612, oldfalc); // AssignLock
- SetFunction(DOSBase, -624, oldfap); // AssignPath
- SetFunction(DOSBase, -636, oldfra); // RemAssignList
-
- SetFunction(DOSBase, -774, oldfas); // AddSegment
- SetFunction(DOSBase, -786, oldfrs); // RemSegment
-
- SetFunction(DOSBase, -900, oldfsv); // SetVar
- SetFunction(DOSBase, -912, oldfdv); // DeleteVar
-
- Permit();
-
- EndNotify(&req);
-
- exit(0);
- }
-
- void main(){
- PutStr(" PatchAssign v1.1 ("__TIME__" "__DATE__")\n"
- "\t© LFSoft 1995\n");
- debut();
- }
-
- void wbmain(){
- debut();
- }